﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;
using EzDesk.Apps.Model.ProjectModule;
using EzDesk.Core.Model;
using EzDesk.ServiceHost.ViewModels;
using EzDesk.Utility.Extensions;
using EzDesk.Utility.Json;
using EzDesk.Utility.Log;
using EzDesk.Utility.ServiceStatusInfo;
using System.Text;
using EzDesk.Utility;
using EzDesk.Utility.Web.Extensions;


namespace EzDesk.ServiceHost.Controllers
{

    public partial class ProjectController
    {
        #region Page
        public ActionResult ProjectTemplate()
        {
            return View(new object());
        }

        public ActionResult ProjectList()
        {
            dynamic model = new ExpandoObject();

            var hasPermissionToCreateProject = _coreAppService.UserHasPermission("PROJECT_CREATE_PROJECT", CurrentUserId);
            model.HasCreateProjectPermission = hasPermissionToCreateProject;

            return View("ProjectList", model);
        }

        //todo: 等完善了再给一个统一入口
        public ActionResult ProjectInfo(Guid id)
        {
            return RedirectToAction("ProjectWorkitems", new { Id = id });
        }

        public ActionResult ProjectMembers(Guid id)
        {
            //todo:
            dynamic model = new ExpandoObject();
            model.ProjectId = id;
            return View(model);
        }

        [HttpGet]
        public JsonResult ProjectWithMembers(Guid id)
        {
            var project = ProjectService.GetProjectById(id).Result;

            var memberList = project.MemberInProject.Select(
                p =>
                {
                    var roleStr = "member";
                    if (p.UserId == project.ChargePersonId) roleStr = "leader";
                    if (p.UserId == project.CreatorId) roleStr = "creator";

                    return new
                    {
                        Member = _coreAppService.GetSimpleUserById(p.UserId),
                        Role = roleStr
                    };
                }).ToList();
            var leader = memberList.FirstOrDefault(p => p.Member.Id == project.ChargePersonId);
            var creator = memberList.FirstOrDefault(p => p.Member.Id == project.CreatorId);

            var projectModel = new
            {
                Id = project.Id,
                Name = project.Name,
                Code = project.Code,
                project.Description,
                CreateOn = project.CreateOn,
                Leader = leader,
                Creator = creator,
                MemberList = memberList,
            };
            return Json(projectModel);
        }

        public ActionResult ProjectWorkitems(Guid id)
        {
            dynamic model = new ExpandoObject();
            //var project = ProjectService.GetProjectById(id).Result;
            //var memberList = project.MemberInProject.Select(p => _coreAppService.GetSimpleUserById(p.UserId))
            //                                        .ToList();
            //model.ProjectInfo = new
            //{
            //    Id = project.Id,
            //    Name = project.Name,
            //    Code = project.Code,
            //    CreateOn = project.CreateOn,
            //    project.Description,
            //    MemberList = memberList,
            //    project.Task
            //};

            model.ProjectId = id;

            return View(model);
        }

        #endregion Page

        #region [ Partial Actions ]
        public ActionResult _createProjectShortcut(bool hasCreateProjectPermission)
        {
            return hasCreateProjectPermission ? View() : null;
        }

        public ActionResult _projectTemplates(bool hasCreateProjectPermission)
        {
            return hasCreateProjectPermission ? View() : null;
        }
        #endregion

        #region [ Ajax ]

        [HttpGet]
        public JsonResult ProjectById(Guid id)
        {
            var project = ProjectService.GetProjectById(id).Result;
            return Json(project, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult GetFullProjectById(Guid id)
        {
            var project = ProjectService.GetFullProjectById(id).Result;
            project.TeamMembers = _coreAppService.GetSimpleUserInfos(project.MemberString);

            if (project.ChargePersonId.HasValue)
                project.Director = _coreAppService.GetSimpleUserById(project.ChargePersonId.Value);

            project.Workitem.PopulateCreatorNameAndOwnerNames();

            return Json(project, JsonRequestBehavior.AllowGet);
        }


        [HttpGet]
        public JsonResult GetAllFullProjects()
        {
            var hasPermissionToCreateProject = _coreAppService.UserHasPermission("PROJECT_CREATE_PROJECT", CurrentUserId);

            List<Project> projectList = null;
            projectList = hasPermissionToCreateProject
                              ? getAllProjects()
                              : getProjectListForUser(CurrentUserId);

            return Json(getProjectListModel(projectList), JsonRequestBehavior.AllowGet);

        }

        [HttpGet]
        public JsonResult GetAllFullProjectsForMobile()
        {
            var hasPermissionToCreateProject = _coreAppService.UserHasPermission("PROJECT_CREATE_PROJECT", CurrentUserId);

            List<Project> projectList = null;
            projectList = hasPermissionToCreateProject
                              ? getAllProjects()
                              : getProjectListForUser(CurrentUserId);

            var list = getProjectListModel(projectList).Where(p => p.StatusValue == 1).ToList();

            return Json(list, JsonRequestBehavior.AllowGet);
        }


        //[HttpGet]
        //public JsonResult GetSimpleProjectListForUser(Guid? userId)
        //{
        //    var projectList = getProjectListForUser(userId);

        //    var projectModel = projectList.Select(project => new
        //    {
        //        project.Name,
        //        project.Id
        //    });

        //    return Json(
        //       projectModel,
        //       JsonRequestBehavior.AllowGet
        //       );
        //}


        [HttpGet]
        public JsonResult GetProjectListForUser(Guid? userId)
        {
            return Json(getProjectListForUser(userId), JsonRequestBehavior.AllowGet);
        }


        [HttpGet]
        public JsonResult GetAllProjects()
        {
            return Json(getAllProjects(), JsonRequestBehavior.AllowGet);
        }


        [HttpPost]
        public ActionResult DoUpdateProjectMemberString(Guid projectId, string memberString)
        {
            var statusInfo = ProjectService.UpdateProjectMember(projectId, memberString, CurrentUserId);
            return Json(statusInfo);
        }

        /// <summary>
        /// 更新项目基本信息方法，参数 = null 则不更新，空字符串也会被更新
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="projectName"></param>
        /// <param name="projectCode"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        [HttpPost]
        [PermissionRequire("PROJECT_EDIT_PROJECT_BASICINFO")]
        public ActionResult DoUpdateProjectBasicInfo(Guid projectId, string projectName, string projectCode, string description)
        {
            var statusInfo = ProjectService.UpdateProjectBasicInfo(projectId, projectName, projectCode, description, CurrentUserId);
            if (statusInfo.Status == ServiceStatus.Success)
            {
                statusInfo.Info = "更新完成";
            }
            return Json(statusInfo);
        }


        [HttpPost]
        [PermissionRequire("PROJECT_EDIT_PROJECT_BASICINFO")]
        public ActionResult SwitchProjectStatus(Guid projectId, ProjectStatus projectStatus)
        {
            var statusInfo = ProjectService.SwitchProjectStatus(projectId, projectStatus, CurrentUserId);
            if (statusInfo.Status == ServiceStatus.Success)
            {
                statusInfo.Info = "项目已" + (projectStatus == ProjectStatus.Archive ? "关闭" : "启动");
            }
            return Json(statusInfo);
        }

        [HttpPost]
        public ActionResult DoCreateProject(string projectName, string projectCode, Guid chargeUserId, Guid? projectTemplateId, string planOn)
        {
            var memberString = "";
            memberString = EzDeskAppApiHelper.MemberStringHelper.JoinUserId(memberString, CurrentUserId);
            memberString = EzDeskAppApiHelper.MemberStringHelper.JoinUserId(memberString, chargeUserId);

            var project = new Project()
            {
                Name = projectName,
                Code = projectCode,
                Description = "",
                ChargePersonId = chargeUserId,
                MemberString = memberString,
                CreatorId = CurrentUserId,
            };
            var planOnDate = string.IsNullOrEmpty(planOn)
                                      ? DateTime.Today
                                      : Convert.ToDateTime(planOn);

            project.PlanOn = planOnDate;

            var statusInfo =
                projectTemplateId.HasValue
                ? ProjectService.CreateNewProjectWithTemplate(project, projectTemplateId.Value, planOnDate, CurrentUserId)
                : ProjectService.CreateNewProject(project);

            if (statusInfo.Status == ServiceStatus.Success)
            {
                statusInfo.Info = "创建项目成功";
                statusInfo.Data = new { projectId = statusInfo.Result.Id.ToString() };
            }
            return Json(statusInfo.ToSimpleStatusInfo());
        }


        [HttpPost]
        public JsonResult CreateProjectTemplate(string projectTemplateStr)
        {
            var projectTemplate = WebJsonExtension.FromJson<ProjectTemplate>(projectTemplateStr);
            var statusInfo = ProjectService.CreateProjectTemplate(projectTemplate);
            if (statusInfo.Status == ServiceStatus.Success)
            {
                statusInfo.Info = "项目模板创建成功";
            }
            return Json(statusInfo);
        }

        [HttpGet]
        public JsonResult GetProjectTemplateList()
        {
            var statusInfo = ProjectService.GetProjectTemplateList();
            if (statusInfo.Status == ServiceStatus.Success)
            {
                return Json(statusInfo.Result);
            }
            return Json("[]");
        }

        [HttpPost]
        public JsonResult RemoveProjectTemplate(Guid id)
        {
            var statusInfo = ProjectService.RemoveProjectTemplate(id);
            return Json(statusInfo);
        }

        [HttpPost]
        public JsonResult ChangeProjectStartOn(Guid projectId, int startOn)
        {
            var startOnDateTime = EpochDateTimeExtension.FromEpoch(startOn);
            var statusInfo = ProjectService.ChangeProjectStartOn(projectId, startOnDateTime, CurrentUserId);
            return Json(statusInfo);
        }

        #region [ For Mobile ]
        [HttpGet]
        public JsonResult GetWorkitemsInProjectForMobile(Guid projectId)
        {
            dynamic data = ProjectService.GetWorkitemsInProjectForMobile(projectId);
                                                //SortedWorkitems = sortedWorkitemList,
                                                //RootTasks = rootTasks,
            var sortedWorkitems = (List<Workitem>) data.SortedWorkitems;
            var rootTasks = (List<Task>) data.RootTasks;
            var workitemToRootTaskDict = (Dictionary<Guid, Guid>) data.WorkitemToRootTaskDict;
            var project = (Project) data.Project;

            var returnRootTasks = new List<dynamic>();
            foreach (var rootTask in rootTasks)
            {
                var returnRootTask = new
                                         {
                                             TaskId = rootTask.Id,
                                             Title = rootTask.Name,
                                             CreateOn = rootTask.CreateOn,
                                             WorkitemCount = workitemToRootTaskDict.Count(p => p.Value == rootTask.Id)
                                             // todo: ...
                                         };
                returnRootTasks.Add(returnRootTask);
            }

            var returnSortedWorkitems = new List<dynamic>();
            foreach (var sortedWorkitem in sortedWorkitems)
            {
                var rootTaskId = Guid.Empty;
                if (workitemToRootTaskDict.ContainsKey(sortedWorkitem.Id))
                {
                    rootTaskId = workitemToRootTaskDict[sortedWorkitem.Id];
                }
                var returnWorkitem = new
                                         {
                                             Status = sortedWorkitem.StatusValue,
                                             WorkitemId = sortedWorkitem.Id,
                                             Title = sortedWorkitem.Title,
                                             PlanOn = sortedWorkitem.PlanOn,
                                             CreateOn = sortedWorkitem.CreateOn,
                                             RootTaskId = rootTaskId,
                                         };
                returnSortedWorkitems.Add(returnWorkitem);
            }

            var projectInfo = new
                                  {
                                      ProjectId = project.Id,
                                      Title = project.Name,
                                  };

            return Json(new {
                            ProjectInfo = projectInfo,
                            RootTasks = returnRootTasks,
                            SortedWorkitems = returnSortedWorkitems,
                        }, JsonRequestBehavior.AllowGet
                        );
        }
        #endregion

        #endregion Ajax

        #region Private Methods

        private List<Project> getProjectListForUser(Guid? userId)
        {
            if (!userId.HasValue)
            {
                userId = CurrentUserId;
            }
            var projectList = ProjectService.GetProjects(userId, null).Result;

            return projectList;
        }

        private List<Project> getAllProjects()
        {
            return ProjectService.GetProjects(null, null).Result;
        }

        private List<dynamic> getProjectListModel(List<Project> projectList)
        {
            var projectModelList = new List<object>();

            var leadIdList = projectList.Select(p => p.ChargePersonId).ToList();
            var memberString = leadIdList.Aggregate("",
                (current, leadId) =>
                    EzDeskAppApiHelper.MemberStringHelper.
                    JoinUserId(current, leadId.Value));
            var leaderList = _coreAppService.GetSimpleUserInfos(memberString).ToList();

            var projectIdList = projectList.Select(p => p.Id).ToList();
            var taskList = ProjectService.GetTasksInProjects(projectIdList).Result;
            var workitemList = ProjectService.GetWorkitemsInProjects(projectIdList).Result;

            foreach (var project in projectList)
            {
                var leader = leaderList.FirstOrDefault(l => l.Id == project.ChargePersonId);

                var tasks = taskList.Where(t => t.ProjectId == project.Id).ToList();
                DateTime? endDate = null;
                
                object dateDiff = null;
                
                if (project.Status != ProjectStatus.Archive && tasks.Count > 0)
                {
                    endDate = tasks.Max(t => t.GetEndDate());
                    dateDiff = (int)(DateTime.Today - endDate.Value).TotalDays;
                }

                var workitems = workitemList.Where(w => w.ProjectId == project.Id).ToList();
                var workitem = new
                {
                    UnfinishedCount = workitems.Where(p => p.StatusValue != 1 && p.StatusValue != 2).Count(),
                    FinishedCount = workitems.Where(p => p.StatusValue == 1).Count(),
                    ExpiredCount = workitems.Where(p => p.StatusValue == 2).Count(),

                };

                var projectModel = new
                                       {
                                           Id = project.Id,
                                           Name = project.Name,
                                           ProjectId = project.Code,
                                           Explanation = project.Description,
                                           CreatOn = project.CreateOn,
                                           Leader = leader,
                                           Workitem = workitem,
                                           EndDate = endDate.HasValue ? endDate.Value.ToEpoch() : -1,
                                           DateDiff = dateDiff,
                                           Status = project.Status,
                                           StatusValue = project.StatusValue
                                       };


                projectModelList.Add(projectModel);
            }

            return projectModelList;
        }

        #endregion
    }
}
